package com.survivor.example;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.survivor.opengl.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;

public class Lessone16Rendder implements Renderer {
	

	private float[] verCoord = { -.5f, -.5f, .5f, .5f, -.5f, .5f, -.5f, .5f,
			.5f, .5f, .5f, .5f,

			-.5f, -.5f, -.5f, -.5f, .5f, -.5f, .5f, -.5f, -.5f, .5f, .5f, -.5f,

			-.5f, .5f, .5f, .5f, .5f, .5f, -.5f, .5f, -.5f, .5f, .5f, -.5f,

			-.5f, -.5f, .5f, -.5f, -.5f, -.5f, .5f, -.5f, .5f, .5f, -.5f, -.5f,

			-.5f, -.5f, .5f, -.5f, .5f, .5f, -.5f, -.5f, -.5f, -.5f, .5f, -.5f,

			.5f, -.5f, .5f, .5f, -.5f, -.5f, .5f, .5f, .5f, .5f, .5f, -.5f

	};

	private float[] texCoord = { 0, 1, 1, 1, 0, 0, 1, 0,

	1, 1, 1, 0, 0, 1, 0, 0,

	0, 1, 1, 1, 0, 0, 1, 0,

	0, 0, 0, 1, 1, 0, 1, 1,

	1, 1, 1, 0, 0, 1, 0, 0,

	0, 1, 1, 1, 0, 0, 1, 0 };

	private float rotX = 0;
	private float rotY = 0;
	private float rotZ = 0;

	private FloatBuffer verBuffer, texBuffer;

	private Bitmap bmp;

	private int[] textures = new int[1];

	private int[] fogMode = { GL10.GL_EXP, GL10.GL_EXP2, GL10.GL_LINEAR };

	private float[] fogColor = { .5f, .5f, .5f, 1f };

	public Lessone16Rendder(Context context) {
		// TODO Auto-generated constructor stub
		bmp = BitmapFactory.decodeResource(context.getResources(),
				R.drawable.crate);

		verBuffer = makeFloatBuffer(verCoord);
		texBuffer = makeFloatBuffer(texCoord);
	}

	private FloatBuffer makeFloatBuffer(float[] src) {
		ByteBuffer bb = ByteBuffer.allocateDirect(src.length * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(src);
		fb.position(0);
		return fb;
	}

	public void onDrawFrame(GL10 gl) {
		// TODO Auto-generated method stub
		doDraw(gl);
	}

	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// TODO Auto-generated method stub
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		GLU.gluPerspective(gl, 45f, (float) width / height, .1f, 10f);
	}

	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		// TODO Auto-generated method stub
		loadFog(gl);
		loadTextures(gl);
	}

	private void loadFog(GL10 gl) {
		gl.glClearColor(0f, 0f, 0f, 1f);
		gl.glFogx(GL10.GL_FOG_MODE, fogMode[0]);
		gl.glFogfv(GL10.GL_FOG_COLOR, fogColor, 0);
		gl.glHint(GL10.GL_FOG_HINT, GL10.GL_NEAREST);
//		gl.glHint(GL10.GL_FOG_HINT, GL10.GL_DONT_CARE);
		gl.glFogf(GL10.GL_FOG_DENSITY, .5f);
		gl.glFogf(GL10.GL_FOG_START, 1f);
		gl.glFogf(GL10.GL_FOG_END, 5f);
		gl.glEnable(GL10.GL_FOG);
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
	}

	private void loadTextures(GL10 gl) {
		// gl.glClearColor(0, 0, 0, 1f);
		gl.glEnable(GL10.GL_TEXTURE_2D);
		gl.glGenTextures(textures.length, textures, 0);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
				GL10.GL_LINEAR);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
				GL10.GL_LINEAR);
		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glClearDepthf(1f);
		gl.glDepthFunc(GL10.GL_LEQUAL);
		gl.glShadeModel(GL10.GL_SMOOTH);
	}

	private void doDraw(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
		GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0);

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		gl.glRotatef(rotX, 1f, 0, 0);
		gl.glRotatef(rotY, 0, 1f, 0);
		gl.glRotatef(rotZ, 0.0f, 0.0f, 1f);

		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verBuffer);

		for (int i = 0; i < 6; i++)
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 4, 4);

		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		rotX += 1;
		rotY += 1;
		rotZ += 1;
	}

}
